/*
 * Filename:    CalculationKpiService.java
 * Copyright:   2014 中国平安保险（集团）股份有限公司 版权所有
 * Company:     平安科技养老险及健康险系统开发部
 * Create at:   2014年10月15日
 */
package com.paic.mhis.hcpms.quota.calculationreport.calculationkpi.biz.service.impl;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.paic.mhis.hcpms.quota.calculationreport.calculationdataItem.dto.CalculationResultDTO;
import com.paic.mhis.hcpms.quota.calculationreport.calculationkpi.biz.service.CalculationKpi;
import com.paic.mhis.hcpms.quota.calculationreport.calculationkpi.biz.service.CalculationKpiService;
import com.paic.mhis.hcpms.quota.calculationreport.calculationkpi.dto.CalculationKpiParmDTO;
import com.paic.mhis.hcpms.quota.calculationreport.calculationkpi.dto.KpiBaseFormulaDTO;
import com.paic.mhis.hcpms.quota.calculationreport.calculationkpi.dto.KpiCalculationOtherDTO;
import com.paic.mhis.hcpms.quota.calculationreport.calculationkpi.dto.KpiCalculationResultDTO;
import com.paic.mhis.hcpms.quota.calculationreport.calculationkpi.intergration.dao.CalculationKpiDAO;
import com.paic.mhis.hcpms.quota.calculationreport.calculationkpi.util.ContextUtil;

@Component("calculationKpiService")
public class CalculationKpiServiceImpl implements CalculationKpiService {
	public static final int ROWS = 5000;
	// 医生人数
	static final String kpicode1 = "KPI0064";
	// 统计期天数
	static final String kpicode2 = "KPI0065";

	public static Log log = LogFactory.getLog(CalculationKpiServiceImpl.class);
	@Autowired
	private CalculationKpiDAO calculationKpiDAO;

	@Override
	public List<KpiBaseFormulaDTO> findKpiCodeAndFormualList(String calType) {
		List<KpiBaseFormulaDTO> formulaList = calculationKpiDAO.findKpiCodeAndFormualList(calType);
		return formulaList;
	}

	public CalculationResultDTO calculationKpi(String areaCode, String period) {
		Date startDate = new Date();
		log.info("-----数据项就诊信息开始START--------" + startDate);
		CalculationKpiParmDTO dto = new CalculationKpiParmDTO();
		CalculationResultDTO resultDto = new CalculationResultDTO();
		dto.setAreaCode(areaCode);

		dto.setKpiTime(period);
		dto.setUserId("hcpmsdata");
		dto.setRows(ROWS);

		dto.setPeriod(ContextUtil.PERIOD_MONTH);
		CalculationKpi calKpi = new CalculationKpi();
		List<KpiBaseFormulaDTO> formulaList = findKpiCodeAndFormualList(ContextUtil.CAL_TYPE_ZERO);
		calKpi.setCalculationFormula(formulaList);

		log.info("--统筹区数据项公式计算开始--");
		dto.setCalculationType(ContextUtil.KPI_SOCIATION);
		dto.setVisitType(ContextUtil.VISIT_TYPE_T);
		calculationSociationKpi(calKpi, dto, resultDto);
		selectAddJyrs(dto);// 就医人数

		dto.setVisitType(ContextUtil.VISIT_TYPE_M);
		calculationSociationKpi(calKpi, dto, resultDto);
		selectAddJyrs(dto);// 就医人数

		dto.setVisitType(ContextUtil.VISIT_TYPE_V);
		calculationSociationKpi(calKpi, dto, resultDto);
		calculationOtheKpi(dto);// 预拨费用计算
		selectAddJyrs(dto);// 就医人数
		selectAddYsrsTjqrs(dto);// 医生人数和统计期天数
		selectAddKghs(dto);// 空挂号数
		calculationKpiRatio(dto);// 同环比计算
		log.info("--统筹区数据项公式计算完成--");

		log.info("--医疗机构等级数据项公式计算开始--");
		dto.setCalculationType(ContextUtil.KPI_GRADE);
		dto.setVisitType(ContextUtil.VISIT_TYPE_T);
		calculationGradeKpi(calKpi, dto, resultDto);
		selectAddJyrs(dto);// 就医人数

		dto.setVisitType(ContextUtil.VISIT_TYPE_M);
		calculationGradeKpi(calKpi, dto, resultDto);
		selectAddJyrs(dto);// 就医人数

		dto.setVisitType(ContextUtil.VISIT_TYPE_V);
		calculationGradeKpi(calKpi, dto, resultDto);
		calculationOtheKpi(dto);// 预拨费用计算
		selectAddJyrs(dto);// 就医人数
		selectAddYsrsTjqrs(dto);// 医生人数和统计期天数
		selectAddKghs(dto);// 空挂号数
		calculationKpiRatio(dto);// 同环比计算
		log.info("--医疗机构等级数据项公式计算结束--");

		log.info("--医疗机构类型数据项公式计算开始--");
		dto.setCalculationType(ContextUtil.KPI_CATEGORY);
		dto.setVisitType(ContextUtil.VISIT_TYPE_T);
		calculationCategoryKpi(calKpi, dto, resultDto);
		selectAddJyrs(dto);// 就医人数

		dto.setVisitType(ContextUtil.VISIT_TYPE_M);
		calculationCategoryKpi(calKpi, dto, resultDto);
		selectAddJyrs(dto);// 就医人数

		dto.setVisitType(ContextUtil.VISIT_TYPE_V);
		calculationCategoryKpi(calKpi, dto, resultDto);
		calculationOtheKpi(dto);// 预拨费用计算
		selectAddJyrs(dto);// 就医人数
		selectAddYsrsTjqrs(dto);// 医生人数和统计期天数
		selectAddKghs(dto);// 空挂号数
		calculationKpiRatio(dto);// 同环比计算
		log.info("--医疗机构类型数据项公式计算结束--");

		log.info("--医院数据项公式计算开始--");
		dto.setCalculationType(ContextUtil.KPI_MEDICAL);
		dto.setVisitType(ContextUtil.VISIT_TYPE_T);
		calculationMedicalKpi(calKpi, dto, resultDto);
		selectAddJyrs(dto);// 就医人数

		dto.setVisitType(ContextUtil.VISIT_TYPE_M);
		calculationMedicalKpi(calKpi, dto, resultDto);
		selectAddJyrs(dto);// 就医人数

		dto.setVisitType(ContextUtil.VISIT_TYPE_V);
		calculationMedicalKpi(calKpi, dto, resultDto);
		selectAddCases(dto);
		selectAddDiagnose(dto);
		selectAddProject(dto);

		selectAddJyrs(dto);// 就医人数
		selectAddYsrsTjqrs(dto);// 医生人数和统计期天数
		calculationOtheKpi(dto);// 预拨费用计算
		selectAddKghs(dto);// 空挂号数
		calculationKpiRatio(dto);// 同环比计算
		log.info("--医院数据项公式计算结束--");

		log.info("--医院科室数据项公式计算开始--");
		dto.setCalculationType(ContextUtil.KPI_DEPART);
		dto.setVisitType(ContextUtil.VISIT_TYPE_T);
		calculationDepartKpi(calKpi, dto, resultDto);
		selectAddJyrs(dto);// 就医人数
		dto.setVisitType(ContextUtil.VISIT_TYPE_M);
		calculationDepartKpi(calKpi, dto, resultDto);
		selectAddJyrs(dto);// 就医人数

		dto.setVisitType(ContextUtil.VISIT_TYPE_V);
		calculationDepartKpi(calKpi, dto, resultDto);
		selectAddJyrs(dto);// 就医人数
		selectAddKghs(dto);// 空挂号数.
		selectAddYsrsTjqrs(dto);// 医生人数和统计期天数
		calculationKpiRatio(dto);// 同环比计算
		log.info("--医院科室数据项公式计算结束--");

		log.info("--医院科室医生数据项公式计算开始--");
		dto.setCalculationType(ContextUtil.KPI_DOCTOR);
		dto.setVisitType(ContextUtil.VISIT_TYPE_T);
		calculationDoctorKpi(calKpi, dto, resultDto);
		selectAddJyrs(dto);// 就医人数

		dto.setVisitType(ContextUtil.VISIT_TYPE_M);
		calculationDoctorKpi(calKpi, dto, resultDto);
		selectAddJyrs(dto);// 就医人数

		dto.setVisitType(ContextUtil.VISIT_TYPE_V);
		calculationDoctorKpi(calKpi, dto, resultDto);
		selectAddJyrs(dto);// 就医人数
		selectAddKghs(dto);// 空挂号数
		selectAddYsrsTjqrs(dto);// 医生人数和统计期天数
		calculationKpiRatio(dto);// 同环比计算

		log.info("--医院科室医生类型数据项公式计算结束--");

		// KPI公式计算
		kpiArithmetiDispose(dto, resultDto);
		Date endDate = new Date();
		log.info("-----数据项就诊信息计算END--------" + endDate);
		return resultDto;

	}

	private void kpiArithmetiDispose(CalculationKpiParmDTO dto, CalculationResultDTO resultDto) {
		log.info("-----指标公式（KPI公式）计算开始----");
		CalculationKpi calKpi2 = new CalculationKpi();
		List<KpiBaseFormulaDTO> formulas = findKpiCodeAndFormualList(ContextUtil.CAL_TYPE_TWO);
		calKpi2.setCalculationFormula(formulas);
		Set<String> kpiCodeSet = new HashSet<String>();
		if (null != formulas && formulas.size() > 0) {
			getKPISets(kpiCodeSet, formulas);
		}
		dto.setParnName(ContextUtil.KEY_CODE);
		log.info("--统筹区维度指标公式计算开始--");// 1
		dto.setCalculationType(ContextUtil.KPI_SOCIATION);
		dto.setVisitType(ContextUtil.VISIT_TYPE_T);
		sociationKpiArithmeti(calKpi2, dto, resultDto, kpiCodeSet);
		dto.setVisitType(ContextUtil.VISIT_TYPE_M);
		sociationKpiArithmeti(calKpi2, dto, resultDto, kpiCodeSet);
		dto.setVisitType(ContextUtil.VISIT_TYPE_V);
		sociationKpiArithmeti(calKpi2, dto, resultDto, kpiCodeSet);
		calculationKpiRatio(dto);
		log.info("--统筹区维度指标公式计算结束--");
		log.info("--医疗机构等级维度指标公式计算开始--");// 2
		dto.setCalculationType(ContextUtil.KPI_GRADE);
		dto.setVisitType(ContextUtil.VISIT_TYPE_T);
		gradeKpiArithmeti(calKpi2, dto, resultDto, kpiCodeSet);
		dto.setVisitType(ContextUtil.VISIT_TYPE_M);
		gradeKpiArithmeti(calKpi2, dto, resultDto, kpiCodeSet);
		dto.setVisitType(ContextUtil.VISIT_TYPE_V);
		gradeKpiArithmeti(calKpi2, dto, resultDto, kpiCodeSet);
		calculationKpiRatio(dto);
		log.info("--医疗机构等级维度指标公式计算结束--");
		log.info("--医疗机构类型维度指标公式计算开始--");// 3
		dto.setCalculationType(ContextUtil.KPI_CATEGORY);
		dto.setVisitType(ContextUtil.VISIT_TYPE_T);
		categoryKpiArithmeti(calKpi2, dto, resultDto, kpiCodeSet);
		dto.setVisitType(ContextUtil.VISIT_TYPE_M);
		categoryKpiArithmeti(calKpi2, dto, resultDto, kpiCodeSet);
		dto.setVisitType(ContextUtil.VISIT_TYPE_V);
		categoryKpiArithmeti(calKpi2, dto, resultDto, kpiCodeSet);
		calculationKpiRatio(dto);
		log.info("--医疗机构类型维度指标公式计算结束--");
		log.info("--医院维度指标公式计算开始--");// 4
		dto.setCalculationType(ContextUtil.KPI_MEDICAL);
		dto.setVisitType(ContextUtil.VISIT_TYPE_T);
		medicalKpiArithmeti(calKpi2, dto, resultDto, kpiCodeSet);
		dto.setVisitType(ContextUtil.VISIT_TYPE_M);
		medicalKpiArithmeti(calKpi2, dto, resultDto, kpiCodeSet);
		dto.setVisitType(ContextUtil.VISIT_TYPE_V);
		medicalKpiArithmeti(calKpi2, dto, resultDto, kpiCodeSet);
		calculationKpiRatio(dto);
		log.info("--医院维度指标公式计算结束--");
		log.info("--医院科室维度指标公式计算开始--");// 5
		dto.setCalculationType(ContextUtil.KPI_DEPART);
		dto.setVisitType(ContextUtil.VISIT_TYPE_T);
		departKpiArithmeti(calKpi2, dto, resultDto, kpiCodeSet);
		dto.setVisitType(ContextUtil.VISIT_TYPE_M);
		departKpiArithmeti(calKpi2, dto, resultDto, kpiCodeSet);
		dto.setVisitType(ContextUtil.VISIT_TYPE_V);
		departKpiArithmeti(calKpi2, dto, resultDto, kpiCodeSet);
		calculationKpiRatio(dto);
		log.info("--医院科室维度指标公式计算结束--");
		log.info("--医院科室医生维度指标公式计算开始--");// 6
		dto.setCalculationType(ContextUtil.KPI_DOCTOR);
		dto.setVisitType(ContextUtil.VISIT_TYPE_T);
		doctorKpiArithmeti(calKpi2, dto, resultDto, kpiCodeSet);
		dto.setVisitType(ContextUtil.VISIT_TYPE_M);
		doctorKpiArithmeti(calKpi2, dto, resultDto, kpiCodeSet);
		dto.setVisitType(ContextUtil.VISIT_TYPE_V);
		doctorKpiArithmeti(calKpi2, dto, resultDto, kpiCodeSet);
		calculationKpiRatio(dto);
		log.info("--医院科室医生维度指标公式计算结束--");
		log.info("-----指标公式（KPI公式）计算结束----");
	}

	private void calculationSociationKpi(CalculationKpi calKpi, CalculationKpiParmDTO dto,
			CalculationResultDTO resultDto) {
		List<Map<String, Object>> kpiDateList = calculationKpiDAO.querySociationData(dto);
		for (Map<String, Object> dataDTO : kpiDateList) {
			List<KpiCalculationResultDTO> sociationList = calKpi.calculationKpi(dto, dataDTO, resultDto);
			try {
				calculationKpiDAO.insertSociationKpiData(sociationList);
			} catch (Exception e) {
				log.error("统筹区数据项公式计算错误：" + e.getCause().getCause().getMessage());
			}
		}
	}

	private void calculationGradeKpi(CalculationKpi calKpi, CalculationKpiParmDTO dto, CalculationResultDTO resultDto) {
		List<Map<String, Object>> kpiDateList = calculationKpiDAO.queryGradeData(dto);
		for (Map<String, Object> dataDTO : kpiDateList) {
			List<KpiCalculationResultDTO> sociationList = calKpi.calculationKpi(dto, dataDTO, resultDto);
			try {
				calculationKpiDAO.insertGradeKpiData(sociationList);
			} catch (Exception e) {
				log.error("医院机构等级数据项公式计算错误：" + e.getCause().getCause().getMessage());
			}
		}
	}

	private void calculationCategoryKpi(CalculationKpi calKpi, CalculationKpiParmDTO dto, CalculationResultDTO resultDto) {
		List<Map<String, Object>> kpiDateList = calculationKpiDAO.queryCategoryData(dto);
		for (Map<String, Object> dataDTO : kpiDateList) {
			List<KpiCalculationResultDTO> sociationList = calKpi.calculationKpi(dto, dataDTO, resultDto);
			try {
				calculationKpiDAO.insertCategoryKpiData(sociationList);
			} catch (Exception e) {
				log.error("医院机构类型数据项公式计算错误：" + e.getCause().getCause().getMessage());
			}
		}

	}

	private void calculationMedicalKpi(CalculationKpi calKpi, CalculationKpiParmDTO dto, CalculationResultDTO resultDto) {
		int totalPage = calculationKpiDAO.queryMedicalTotalPage(dto);
		if (totalPage > 0) {
			for (int i = 1; i <= totalPage; i++) {
				dto.setPage(i);
				List<Map<String, Object>> kpiDateList = calculationKpiDAO.queryMedicalData(dto);
				for (Map<String, Object> dataDTO : kpiDateList) {
					List<KpiCalculationResultDTO> sociationList = calKpi.calculationKpi(dto, dataDTO, resultDto);
					try {
						calculationKpiDAO.insertMedicalKpiData(sociationList);
					} catch (Exception e) {
						log.error("医院数据项公式计算错误：" + e.getCause().getCause().getMessage());
					}
				}
			}
		}

	}

	private void calculationDepartKpi(CalculationKpi calKpi, CalculationKpiParmDTO dto, CalculationResultDTO resultDto) {
		int totalPage = calculationKpiDAO.queryDepartTotalPage(dto);
		if (totalPage > 0) {
			for (int i = 1; i <= totalPage; i++) {
				dto.setPage(i);
				List<Map<String, Object>> kpiDateList = calculationKpiDAO.queryDepartData(dto);
				for (Map<String, Object> dataDTO : kpiDateList) {
					List<KpiCalculationResultDTO> sociationList = calKpi.calculationKpi(dto, dataDTO, resultDto);
					try {
						calculationKpiDAO.insertDepartKpiData(sociationList);
					} catch (Exception e) {
						log.error("医院科室数据项公式计算错误：" + e.getCause().getCause().getMessage());
					}
				}
			}
		}

	}

	private void calculationDoctorKpi(CalculationKpi calKpi, CalculationKpiParmDTO dto, CalculationResultDTO resultDto) {
		int totalPage = calculationKpiDAO.queryDoctorTotalPage(dto);
		if (totalPage > 0) {
			for (int i = 1; i <= totalPage; i++) {
				dto.setPage(i);
				List<Map<String, Object>> kpiDateList = calculationKpiDAO.queryDoctorData(dto);
				for (Map<String, Object> dataDTO : kpiDateList) {
					List<KpiCalculationResultDTO> sociationList = calKpi.calculationKpi(dto, dataDTO, resultDto);
					try {
						calculationKpiDAO.insertDoctorKpiData(sociationList);
					} catch (Exception e) {
						log.error("医院医生数据项公式计算错误：" + e.getCause().getCause().getMessage());
					}
				}
			}
		}

	}

	public void calculationKpiRatio(CalculationKpiParmDTO dto) {
		try {
			log.info("------同环比计算开始------");
			calculationKpiDAO.calculationKpiRatio(dto);
			log.info("------同环比计算结束------");
		} catch (Exception e) {
			log.error(dto.getCalculationType() + "同环比计算错误：" + e.getCause().getCause().getMessage());
		}
	}

	public void calculationKpiAdvance(KpiCalculationOtherDTO dto) {
		calculationKpiDAO.calculationKpiAdvance(dto);
	}

	/**
	 * 统筹区维度（KPI公式）计算
	 * 
	 * @param calKpi
	 * @param dto
	 * @param resultDto
	 */
	private void sociationKpiArithmeti(CalculationKpi calKpi, CalculationKpiParmDTO dto,
			CalculationResultDTO resultDto, Set<String> kpiCodeSet) {
		if (null != kpiCodeSet && kpiCodeSet.size() > 0) {
			dto.setKpiCodeList(kpiCodeSet.toArray());
			List<Map<String, Object>> kpiDateList = calculationKpiDAO.querySociationKpi(dto);
			kpiDateList = encapsulAtionData(dto, kpiDateList);
			if (null != kpiDateList && kpiDateList.size() > 0) {
				for (Map<String, Object> dataDTO : kpiDateList) {
					List<KpiCalculationResultDTO> sociationList = calKpi.calculationKpi(dto, dataDTO, resultDto);
					try {
						addSociationKpiData(sociationList);
					} catch (Exception e) {
						log.error("统筹区维度指标公式计算错误：" + e.getCause().getCause().getMessage());
					}
				}
			} else {
				log.info("统筹区维度指标公式计算没有获取到数据");
			}
		} else {
			log.info("没有需要用指标公式计算的指标");
		}

	}

	/**
	 * 医院等级维度（KPI公式）计算
	 * 
	 * @param calKpi
	 * @param dto
	 * @param resultDto
	 */
	private void gradeKpiArithmeti(CalculationKpi calKpi, CalculationKpiParmDTO dto, CalculationResultDTO resultDto,
			Set<String> kpiCodeSet) {
		if (null != kpiCodeSet && kpiCodeSet.size() > 0) {
			dto.setKpiCodeList(kpiCodeSet.toArray());
			List<Map<String, Object>> kpiDateList = calculationKpiDAO.queryGradeKpi(dto);
			kpiDateList = encapsulAtionData(dto, kpiDateList);
			if (null != kpiDateList && kpiDateList.size() > 0) {
				for (Map<String, Object> dataDTO : kpiDateList) {
					List<KpiCalculationResultDTO> sociationList = calKpi.calculationKpi(dto, dataDTO, resultDto);
					try {
						addGradeKpiData(sociationList);
					} catch (Exception e) {
						log.error("医院等级维度指标公式计算错误：" + e.getCause().getCause().getMessage());
					}
				}
			} else {
				log.info("医院等级维度指标公式计算没有获取到数据");
			}
		} else {
			log.info("没有需要用指标公式计算的指标");
		}

	}

	/**
	 * 医院类型维度（KPI公式）计算
	 * 
	 * @param calKpi
	 * @param dto
	 * @param resultDto
	 */
	private void categoryKpiArithmeti(CalculationKpi calKpi, CalculationKpiParmDTO dto, CalculationResultDTO resultDto,
			Set<String> kpiCodeSet) {
		if (null != kpiCodeSet && kpiCodeSet.size() > 0) {
			dto.setKpiCodeList(kpiCodeSet.toArray());
			List<Map<String, Object>> kpiDateList = calculationKpiDAO.queryCateKpi(dto);
			kpiDateList = encapsulAtionData(dto, kpiDateList);
			if (null != kpiDateList && kpiDateList.size() > 0) {
				for (Map<String, Object> dataDTO : kpiDateList) {
					List<KpiCalculationResultDTO> sociationList = calKpi.calculationKpi(dto, dataDTO, resultDto);
					try {
						addCategoryKpiData(sociationList);
					} catch (Exception e) {
						log.error("医院类型维度指标公式计算错误：" + e.getCause().getCause().getMessage());
					}
				}
			} else {
				log.info("医院类型维度公式计算没有获取到数据");
			}
		} else {
			log.info("没有需要用指标公式计算的指标");
		}

	}

	/**
	 * 医院维度（KPI公式）计算
	 * 
	 * @param calKpi
	 * @param dto
	 * @param resultDto
	 */
	private void medicalKpiArithmeti(CalculationKpi calKpi, CalculationKpiParmDTO dto, CalculationResultDTO resultDto,
			Set<String> kpiCodeSet) {
		if (null != kpiCodeSet && kpiCodeSet.size() > 0) {
			dto.setKpiCodeList(kpiCodeSet.toArray());
			List<Map<String, Object>> kpiDateList = calculationKpiDAO.queryMedorgKpi(dto);
			kpiDateList = encapsulAtionData(dto, kpiDateList);
			if (null != kpiDateList && kpiDateList.size() > 0) {
				for (Map<String, Object> dataDTO : kpiDateList) {
					List<KpiCalculationResultDTO> sociationList = calKpi.calculationKpi(dto, dataDTO, resultDto);
					try {
						addMedicalKpiData(sociationList);
					} catch (Exception e) {
						log.error("医院维度指标公式计算错误：" + e.getCause().getCause().getMessage());
					}
				}
			} else {
				log.info("医院维度指标公式计算没有获取到数据");
			}
		} else {
			log.info("没有需要用指标公式计算的指标");
		}

	}

	/**
	 * 医院科室维度（KPI公式）计算
	 * 
	 * @param calKpi
	 * @param dto
	 * @param resultDto
	 */
	private void departKpiArithmeti(CalculationKpi calKpi, CalculationKpiParmDTO dto, CalculationResultDTO resultDto,
			Set<String> kpiCodeSet) {
		if (null != kpiCodeSet && kpiCodeSet.size() > 0) {
			dto.setKpiCodeList(kpiCodeSet.toArray());
			dto.setRows(ROWS);
			List<Map<String, Object>> kpiDateList = new ArrayList<Map<String, Object>>();
			int totalPage = calculationKpiDAO.queryDeptKpiPage(dto);
			if (totalPage > 0) {
				for (int i = 1; i <= totalPage; i++) {
					dto.setPage(i);
					kpiDateList.addAll(calculationKpiDAO.queryDeptKpi(dto));
				}
			}
			kpiDateList = encapsulAtionData(dto, kpiDateList);
			if (null != kpiDateList && kpiDateList.size() > 0) {
				for (Map<String, Object> dataDTO : kpiDateList) {
					List<KpiCalculationResultDTO> sociationList = calKpi.calculationKpi(dto, dataDTO, resultDto);
					try {
						addDepartKpiData(sociationList);
					} catch (Exception e) {
						log.error("医院科室指标公式计算错误：" + e.getCause().getCause().getMessage());
					}
				}
			} else {
				log.info("医院科室指标公式计算没有获取到数据");
			}
		} else {
			log.info("没有需要用指标公式计算的指标");
		}

	}

	/**
	 * 医院科室医生维度（KPI公式）计算
	 * 
	 * @param calKpi
	 * @param dto
	 * @param resultDto
	 */
	private void doctorKpiArithmeti(CalculationKpi calKpi, CalculationKpiParmDTO dto, CalculationResultDTO resultDto,
			Set<String> kpiCodeSet) {
		if (null != kpiCodeSet && kpiCodeSet.size() > 0) {
			dto.setKpiCodeList(kpiCodeSet.toArray());
			dto.setRows(ROWS);
			List<Map<String, Object>> kpiDateList = new ArrayList<Map<String, Object>>();
			int totalPage = calculationKpiDAO.queryDoctorKpiPage(dto);
			if (totalPage > 0) {
				for (int i = 1; i <= totalPage; i++) {
					dto.setPage(i);
					kpiDateList.addAll(calculationKpiDAO.queryDoctorKpi(dto));
				}
			}
			kpiDateList = encapsulAtionData(dto, kpiDateList);
			if (null != kpiDateList && kpiDateList.size() > 0) {
				for (Map<String, Object> dataDTO : kpiDateList) {
					List<KpiCalculationResultDTO> sociationList = calKpi.calculationKpi(dto, dataDTO, resultDto);
					try {
						addDoctorKpiData(sociationList);
					} catch (Exception e) {
						log.error("医院科室医生维度指标公式计算错误：" + e.getCause().getCause().getMessage());
					}
				}
			} else {
				log.info("医院科室医生维度指标公式计算没有获取到数据");
			}
		} else {
			log.info("没有需要用指标公式计算的指标");
		}

	}

	/**
	 * 新增统筹区维度表
	 * 
	 * @param sociationList
	 */
	private void addSociationKpiData(List<KpiCalculationResultDTO> sociationList) {
		if (null != sociationList && sociationList.size() > 0) {
			calculationKpiDAO.insertSociationKpiData(sociationList);
		}
	}

	/**
	 * 新增医院等级维度表
	 * 
	 * @param sociationList
	 */
	private void addGradeKpiData(List<KpiCalculationResultDTO> sociationList) {
		if (null != sociationList && sociationList.size() > 0) {
			calculationKpiDAO.insertGradeKpiData(sociationList);
		}
	}

	/**
	 * 新增医院类型维度表
	 * 
	 * @param sociationList
	 */
	private void addCategoryKpiData(List<KpiCalculationResultDTO> sociationList) {
		if (null != sociationList && sociationList.size() > 0) {
			calculationKpiDAO.insertCategoryKpiData(sociationList);
		}
	}

	/**
	 * 新增医院维度表
	 * 
	 * @param sociationList
	 */
	private void addMedicalKpiData(List<KpiCalculationResultDTO> sociationList) {
		if (null != sociationList && sociationList.size() > 0) {
			calculationKpiDAO.insertMedicalKpiData(sociationList);
		}
	}

	/**
	 * 新增统医院科室维度表
	 * 
	 * @param sociationList
	 */
	private void addDepartKpiData(List<KpiCalculationResultDTO> sociationList) {
		if (null != sociationList && sociationList.size() > 0) {
			calculationKpiDAO.insertDepartKpiData(sociationList);
		}
	}

	/**
	 * 新增医院科室医生维度表
	 * 
	 * @param sociationList
	 */
	private void addDoctorKpiData(List<KpiCalculationResultDTO> sociationList) {
		if (null != sociationList && sociationList.size() > 0) {
			calculationKpiDAO.insertDoctorKpiData(sociationList);
		}
	}

	/**
	 * 封装数据结果集
	 * 
	 * @param dto
	 * @param kpiDateList
	 * @param querySociationKpi
	 */
	private List<Map<String, Object>> encapsulAtionData(CalculationKpiParmDTO dto,
			List<Map<String, Object>> queryKpiData) {
		List<Map<String, Object>> kpireturnList = new ArrayList<Map<String, Object>>();
		for (Map<String, Object> kpi : queryKpiData) {
			boolean flag = false;
			for (Map<String, Object> kpireturn : kpireturnList) {
				if (kpireturn.get(dto.getParnName()).equals(kpi.get(dto.getParnName()))) {
					kpireturn.put(kpi.get(ContextUtil.KPI_CODE).toString(), kpi.get(ContextUtil.KPI_VALUE));
					flag = true;
					break;
				}
			}
			if (flag == false) {
				Map<String, Object> kpireturn = new HashMap<String, Object>();
				kpireturn.putAll(kpi);
				kpireturn.put(kpi.get(ContextUtil.KPI_CODE).toString(), kpi.get(ContextUtil.KPI_VALUE));
				kpireturnList.add(kpireturn);
			}
		}

		return kpireturnList;

	}

	/**
	 * 获取KPICode集合
	 * 
	 * @param kpiCodeSet
	 * @param formualList
	 */
	private void getKPISets(Set<String> kpiCodeSet, List<KpiBaseFormulaDTO> formualList) {
		for (KpiBaseFormulaDTO formulaDTO : formualList) {
			Set<String> kpiCodes = getKpiCode(formulaDTO.getFormula());
			for (String kpicode : kpiCodes) {
				kpiCodeSet.add(kpicode);
			}
		}
	}

	public void calculationVisitTypeKpi(CalculationKpi calKpi, CalculationKpiParmDTO dto, CalculationResultDTO resultDto) {
		String[] visitTypeArray = { ContextUtil.VISIT_TYPE_T, ContextUtil.VISIT_TYPE_M, ContextUtil.VISIT_TYPE_V };
		for (String visitType : visitTypeArray) {
			dto.setVisitType(visitType);
			if (ContextUtil.KPI_SOCIATION.equals(dto.getCalculationType())) {
				calculationSociationKpi(calKpi, dto, resultDto);
			} else if (ContextUtil.KPI_GRADE.equals(dto.getCalculationType())) {
				calculationGradeKpi(calKpi, dto, resultDto);
			} else if (ContextUtil.KPI_CATEGORY.equals(dto.getCalculationType())) {
				calculationCategoryKpi(calKpi, dto, resultDto);
			} else if (ContextUtil.KPI_MEDICAL.equals(dto.getCalculationType())) {
				calculationMedicalKpi(calKpi, dto, resultDto);
			} else if (ContextUtil.KPI_DEPART.equals(dto.getCalculationType())) {
				calculationDepartKpi(calKpi, dto, resultDto);
			} else if (ContextUtil.KPI_DOCTOR.equals(dto.getCalculationType())) {
				calculationDoctorKpi(calKpi, dto, resultDto);
			}
		}

	}

	public void calculationOtheKpi(CalculationKpiParmDTO dto) {
		String kpiCode = "KPI0003";
		String formKpiCode = "KPI0024";
		KpiCalculationOtherDTO otherDTO = new KpiCalculationOtherDTO();
		otherDTO.setKpiCode(kpiCode);
		otherDTO.setCalculationType(dto.getCalculationType());
		otherDTO.setKpiTime(dto.getKpiTime());
		otherDTO.setPeriod(dto.getPeriod());
		otherDTO.setUseId(dto.getUserId());
		otherDTO.setFromKpiCode(formKpiCode);
		otherDTO.setSociationCode(dto.getAreaCode());

		try {
			calculationKpiAdvance(otherDTO);
		} catch (Exception e) {
			log.error(dto.getCalculationType() + "预拨费用计算错误：" + e.getCause().getCause().getMessage());
		}
	}

	/***
	 * 空挂号数参数封装
	 * 
	 * @param dto
	 */
	public void selectAddKghs(CalculationKpiParmDTO dto) {
		String kpiCode = "KPI0038";
		KpiCalculationOtherDTO otherDTO = new KpiCalculationOtherDTO();
		otherDTO.setKpiCode(kpiCode);
		otherDTO.setCalculationType(dto.getCalculationType());
		otherDTO.setKpiTime(dto.getKpiTime());
		otherDTO.setPeriod(dto.getPeriod());
		otherDTO.setUseId(dto.getUserId());
		otherDTO.setSociationCode(dto.getAreaCode());

		// 根据KpiTime 求月份开始和结束时间
		SimpleDateFormat sft = new SimpleDateFormat("yyyy-MM");
		Date date;
		try {
			date = sft.parse(dto.getKpiTime());
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			otherDTO.setStrDate(cal.getTime());
			cal.add(Calendar.MONTH, 1);
			otherDTO.setEndDate(cal.getTime());
		} catch (ParseException e1) {

			e1.printStackTrace();
		}

		try {
			selectAllhsList(otherDTO);
		} catch (Exception e) {
			log.error(dto.getCalculationType() + "空挂号数计算错误：" + e.getCause().getCause().getMessage());
		}
	}

	/**
	 * KPI截取
	 * 
	 * @param str
	 * @return
	 */
	private static Set<String> getKpiCode(String str) {
		Set<String> set = new HashSet<String>();
		if (str != null) {
			String[] split = str.split("K");
			for (int i = 0; i < split.length; i++) {
				if (split[i].length() > 1) {
					set.add("K" + split[i].substring(0, 6));
				}
			}
		}
		return set;
	}

	/***
	 * 查询空挂号数List
	 * 
	 * @Override
	 * @param dto
	 */
	public void selectAllhsList(KpiCalculationOtherDTO otherDTO) {
		// 统筹区
		if (ContextUtil.KPI_SOCIATION.equals(otherDTO.getCalculationType())) {
			List<KpiCalculationResultDTO> list = calculationKpiDAO.selectSociaTionKghs(otherDTO);
			if (list != null && list.size() > 0) {
				calculationKpiDAO.insertSociationKpiData(list);
			}
		}
		// 医院类型
		else if (ContextUtil.KPI_CATEGORY.equals(otherDTO.getCalculationType())) {
			List<KpiCalculationResultDTO> list = calculationKpiDAO.selectCateKghs(otherDTO);
			if (list != null && list.size() > 0) {
				calculationKpiDAO.insertCategoryKpiData(list);
			}
		}
		// 医院等级
		else if (ContextUtil.KPI_GRADE.equals(otherDTO.getCalculationType())) {
			List<KpiCalculationResultDTO> list = calculationKpiDAO.selectGradeKghs(otherDTO);
			if (list != null && list.size() > 0) {
				calculationKpiDAO.insertGradeKpiData(list);
			}
		}
		// 医院 分组
		else if (ContextUtil.KPI_MEDICAL.equals(otherDTO.getCalculationType())) {
			List<KpiCalculationResultDTO> list = calculationKpiDAO.selectMedOrgKghs(otherDTO);
			if (list != null && list.size() > 0) {
				calculationKpiDAO.insertMedicalKpiData(list);
			}
		}// 医院、科室分组
		else if (ContextUtil.KPI_DEPART.equals(otherDTO.getCalculationType())) {
			List<KpiCalculationResultDTO> list = calculationKpiDAO.selectDeptKghs(otherDTO);
			if (list != null && list.size() > 0) {
				calculationKpiDAO.insertDepartKpiData(list);
			}
		}// 医院、科室、医生分组
		else if (ContextUtil.KPI_DOCTOR.equals(otherDTO.getCalculationType())) {
			List<KpiCalculationResultDTO> list = calculationKpiDAO.selectDocTtorKghs(otherDTO);
			if (list != null && list.size() > 0) {
				calculationKpiDAO.insertDoctorKpiData(list);
			}
		}
	}

	/***
	 * 就医人数参数封装
	 * 
	 * @param dto
	 */
	public void selectAddJyrs(CalculationKpiParmDTO dto) {
		String kpiCode = "KPI0039";
		KpiCalculationOtherDTO otherDTO = new KpiCalculationOtherDTO();
		otherDTO.setKpiCode(kpiCode);
		otherDTO.setCalculationType(dto.getCalculationType());
		otherDTO.setKpiTime(dto.getKpiTime());
		otherDTO.setPeriod(dto.getPeriod());
		otherDTO.setUseId(dto.getUserId());
		otherDTO.setSociationCode(dto.getAreaCode());
		otherDTO.setVisitType(dto.getVisitType());

		// 根据KpiTime 求月份开始和结束时间
		SimpleDateFormat sft = new SimpleDateFormat("yyyy-MM");
		Date date;
		try {
			date = sft.parse(dto.getKpiTime());
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			otherDTO.setStrDate(cal.getTime());
			cal.add(Calendar.MONTH, 1);
			otherDTO.setEndDate(cal.getTime());
		} catch (ParseException e1) {

			e1.printStackTrace();
		}
		try {
			selectAllJyrsList(otherDTO);
		} catch (Exception e) {
			log.error(dto.getCalculationType() + "就医人数计算错误：" + e.getCause().getCause().getMessage());
		}
	}

	/***
	 * 查询就医人数List
	 * 
	 * @Override
	 * @param dto
	 */
	public void selectAllJyrsList(KpiCalculationOtherDTO otherDTO) {
		// 统筹区
		if (ContextUtil.KPI_SOCIATION.equals(otherDTO.getCalculationType())) {
			List<KpiCalculationResultDTO> list = calculationKpiDAO.selectSociaTionJyrs(otherDTO);
			if (list != null && list.size() > 0) {
				for (KpiCalculationResultDTO kpiCRDTO : list) {
					kpiCRDTO.setVisitType(otherDTO.getVisitType());
				}
				calculationKpiDAO.insertSociationKpiData(list);
			}
		}
		// 医院类型
		else if (ContextUtil.KPI_CATEGORY.equals(otherDTO.getCalculationType())) {
			List<KpiCalculationResultDTO> list = calculationKpiDAO.selectCateJyrs(otherDTO);
			if (list != null && list.size() > 0) {
				for (KpiCalculationResultDTO kpiCRDTO : list) {
					kpiCRDTO.setVisitType(otherDTO.getVisitType());
				}
				calculationKpiDAO.insertCategoryKpiData(list);
			}
		}
		// 医院等级
		else if (ContextUtil.KPI_GRADE.equals(otherDTO.getCalculationType())) {
			List<KpiCalculationResultDTO> list = calculationKpiDAO.selectGradeJyrs(otherDTO);
			if (list != null && list.size() > 0) {
				for (KpiCalculationResultDTO kpiCRDTO : list) {
					kpiCRDTO.setVisitType(otherDTO.getVisitType());
				}
				calculationKpiDAO.insertGradeKpiData(list);
			}
		}
		// 医院 分组
		else if (ContextUtil.KPI_MEDICAL.equals(otherDTO.getCalculationType())) {
			List<KpiCalculationResultDTO> list = calculationKpiDAO.selectMedOrgJyrs(otherDTO);
			if (list != null && list.size() > 0) {
				for (KpiCalculationResultDTO kpiCRDTO : list) {
					kpiCRDTO.setVisitType(otherDTO.getVisitType());
				}
				calculationKpiDAO.insertMedicalKpiData(list);
			}
		}// 医院、科室分组
		else if (ContextUtil.KPI_DEPART.equals(otherDTO.getCalculationType())) {
			List<KpiCalculationResultDTO> list = calculationKpiDAO.selectDeptJyrs(otherDTO);
			if (list != null && list.size() > 0) {
				for (KpiCalculationResultDTO kpiCRDTO : list) {
					kpiCRDTO.setVisitType(otherDTO.getVisitType());
				}
				calculationKpiDAO.insertDepartKpiData(list);
			}
		}// 医院、科室、医生分组
		else if (ContextUtil.KPI_DOCTOR.equals(otherDTO.getCalculationType())) {
			List<KpiCalculationResultDTO> list = calculationKpiDAO.selectDocTtorJyrs(otherDTO);
			if (list != null && list.size() > 0) {
				for (KpiCalculationResultDTO kpiCRDTO : list) {
					kpiCRDTO.setVisitType(otherDTO.getVisitType());
				}
				calculationKpiDAO.insertDoctorKpiData(list);
			}
		}
	}

	/***
	 * 医生人数和统计期天数 统筹区 开始查询并组装数据
	 * 
	 * @return
	 */
	public void selectSociaTionYsrsTjqrs(KpiCalculationOtherDTO dto) {

		try {
			List<KpiCalculationResultDTO> lidto = new ArrayList<KpiCalculationResultDTO>();
			List<KpiCalculationResultDTO> list = calculationKpiDAO.selectSociaTionYsrsTjqrs(dto);
			if (null != list && list.size() > 0) {
				setCalculationDtos(lidto, list);
			}

			if (lidto.size() > 0) {
				calculationKpiDAO.insertSociationKpiData(lidto);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void setCalculationDtos(List<KpiCalculationResultDTO> lidto, List<KpiCalculationResultDTO> list) {
		for (KpiCalculationResultDTO dt : list) {
			KpiCalculationResultDTO obj = new KpiCalculationResultDTO();
			BeanUtils.copyProperties(dt, obj);
			obj.setKpiCode(kpicode2);
			obj.setKpiValue(dt.getKpiParm1());
			obj.setKpiParm1(new BigDecimal(0));
			lidto.add(obj);
		}
		for (KpiCalculationResultDTO dt2 : list) {
			KpiCalculationResultDTO obj2 = new KpiCalculationResultDTO();
			BeanUtils.copyProperties(dt2, obj2);
			obj2.setKpiCode(kpicode1);
			obj2.setKpiValue(dt2.getKpiParm2());
			obj2.setKpiParm2(new BigDecimal(0));
			lidto.add(obj2);
		}
	}

	/***
	 * 医生人数和统计期天数 统筹区、医院 开始查询并组装数据
	 * 
	 * @return
	 */
	public void selectMedOrgYsrsTjqrs(KpiCalculationOtherDTO dto) {

		List<KpiCalculationResultDTO> lidto = new ArrayList<KpiCalculationResultDTO>();
		List<KpiCalculationResultDTO> list = calculationKpiDAO.selectMedOrgYsrsTjqrs(dto);
		if (null != list && list.size() > 0) {
			setCalculationDtos(lidto, list);
		}
		if (lidto.size() > 0) {

			calculationKpiDAO.insertMedicalKpiData(lidto);
		}
	}

	/***
	 * 医生人数和统计期天数 统筹区、医院、科室 开始查询并组装数据
	 * 
	 * @return
	 */
	public void selectDeptYsrsTjqrs(KpiCalculationOtherDTO dto) {

		List<KpiCalculationResultDTO> lidto = new ArrayList<KpiCalculationResultDTO>();
		List<KpiCalculationResultDTO> list = calculationKpiDAO.selectDeptYsrsTjqrs(dto);
		if (null != list && list.size() > 0) {
			setCalculationDtos(lidto, list);
		}
		if (lidto.size() > 0) {
			calculationKpiDAO.insertDepartKpiData(lidto);
		}
	}

	/***
	 * 医生人数和统计期天数 统筹区、医院、科室、医生 开始查询并组装数据
	 * 
	 * @return
	 */
	public void selectDocTtorYsrsTjqrs(KpiCalculationOtherDTO dto) {

		List<KpiCalculationResultDTO> lidto = new ArrayList<KpiCalculationResultDTO>();
		List<KpiCalculationResultDTO> list = calculationKpiDAO.selectDocTtorYsrsTjqrs(dto);
		if (null != list && list.size() > 0) {
			setCalculationDtos(lidto, list);
		}
		if (lidto.size() > 0) {
			calculationKpiDAO.insertDoctorKpiData(lidto);
		}
	}

	/***
	 * 医生人数和统计期天数 统筹区、医院类型 开始查询并组装数据
	 * 
	 * @return
	 */
	public void selectCateYsrsTjqrs(KpiCalculationOtherDTO dto) {

		List<KpiCalculationResultDTO> lidto = new ArrayList<KpiCalculationResultDTO>();
		List<KpiCalculationResultDTO> list = calculationKpiDAO.selectCateYsrsTjqrs(dto);
		if (null != list && list.size() > 0) {
			setCalculationDtos(lidto, list);
		}
		if (lidto.size() > 0) {
			calculationKpiDAO.insertCategoryKpiData(lidto);
		}
	}

	/***
	 * 医生人数和统计期天数 统筹区、医院类型 开始查询并组装数据
	 * 
	 * @return
	 */
	public void selectGradeYsrsTjqrs(KpiCalculationOtherDTO dto) {

		List<KpiCalculationResultDTO> lidto = new ArrayList<KpiCalculationResultDTO>();
		List<KpiCalculationResultDTO> list = calculationKpiDAO.selectGradeYsrsTjqrs(dto);
		if (null != list && list.size() > 0) {
			setCalculationDtos(lidto, list);
		}
		if (lidto.size() > 0) {
			calculationKpiDAO.insertGradeKpiData(lidto);
		}
	}

	/***
	 * 医生人数和统计期天数 统筹区 List
	 * 
	 * @Override
	 * @param dto
	 */
	public void selectAllYsrsTjqrsList(KpiCalculationOtherDTO otherDTO) {
		// 统筹区
		if (ContextUtil.KPI_SOCIATION.equals(otherDTO.getCalculationType())) {
			selectSociaTionYsrsTjqrs(otherDTO);
		}
		// 医院类型
		else if (ContextUtil.KPI_CATEGORY.equals(otherDTO.getCalculationType())) {
			selectCateYsrsTjqrs(otherDTO);
		}
		// 医院等级
		else if (ContextUtil.KPI_GRADE.equals(otherDTO.getCalculationType())) {
			selectGradeYsrsTjqrs(otherDTO);
		}
		// 医院 分组
		else if (ContextUtil.KPI_MEDICAL.equals(otherDTO.getCalculationType())) {
			selectMedOrgYsrsTjqrs(otherDTO);
		}// 医院、科室分组
		else if (ContextUtil.KPI_DEPART.equals(otherDTO.getCalculationType())) {
			selectDeptYsrsTjqrs(otherDTO);
		}// 医院、科室、医生分组
		else if (ContextUtil.KPI_DOCTOR.equals(otherDTO.getCalculationType())) {
			selectDocTtorYsrsTjqrs(otherDTO);
		}
	}

	/***
	 * 医生人数和统计期天数 参数封装
	 * 
	 * @param dto
	 */
	public void selectAddYsrsTjqrs(CalculationKpiParmDTO dto) {
		KpiCalculationOtherDTO otherDTO = new KpiCalculationOtherDTO();
		otherDTO.setCalculationType(dto.getCalculationType());
		otherDTO.setKpiTime(dto.getKpiTime());
		otherDTO.setPeriod(dto.getPeriod());
		otherDTO.setUseId(dto.getUserId());
		otherDTO.setSociationCode(dto.getAreaCode());
		otherDTO.setVisitType(dto.getVisitType());
		// 根据KpiTime 求月份开始和结束时间
		SimpleDateFormat sft = new SimpleDateFormat("yyyy-MM");
		Date date;
		try {
			date = sft.parse(dto.getKpiTime());
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			otherDTO.setStrDate(cal.getTime());
			cal.add(Calendar.MONTH, 1);
			otherDTO.setEndDate(cal.getTime());
		} catch (ParseException e1) {

			e1.printStackTrace();
		}
		try {
			selectAllYsrsTjqrsList(otherDTO);
		} catch (Exception e) {
			log.error(dto.getCalculationType() + "医生人数和统计期天数计算错误：" + e.getCause().getCause().getMessage());
		}
	}

	// =====================================================
	/**
	 * 三大目录数据完成对照比例计算
	 * 
	 * @param dto
	 */
	public void selectAddProject(CalculationKpiParmDTO dto) {
		KpiCalculationOtherDTO otherDTO = new KpiCalculationOtherDTO();
		otherDTO.setKpiCode("KPI0068");
		otherDTO.setKpiTime(dto.getKpiTime());
		try {
			SimpleDateFormat sft = new SimpleDateFormat("yyyy-MM");
			Date date = sft.parse(dto.getKpiTime());
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			otherDTO.setStrDate(cal.getTime());
			cal.add(Calendar.MONTH, 1);
			otherDTO.setEndDate(cal.getTime());
			calculationMedicalProject(otherDTO);
		} catch (Exception e) {
			log.error(dto.getCalculationType() + "三大目录数据完成对照比例计算错误：" + e.getCause().getCause().getMessage());
		}
	}

	private void calculationMedicalProject(KpiCalculationOtherDTO otherDTO) {
		otherDTO.setUseId("hcpmsdata");
		otherDTO.setVisitType("0");
		otherDTO.setIsValid("0");
		otherDTO.setPeriod("13");
		List<KpiCalculationResultDTO> list = new ArrayList<KpiCalculationResultDTO>();
		List<KpiCalculationResultDTO> detailCount = calculationKpiDAO.selectDetailProjectCount(otherDTO);
		List<KpiCalculationResultDTO> threeCount = calculationKpiDAO.selectThreeProjectCount(otherDTO);
		for (KpiCalculationResultDTO threeResultDTO : threeCount) {
			KpiCalculationResultDTO resultDto = null;
			for (KpiCalculationResultDTO detailResultDTO : detailCount) {
				resultDto = setKpiResultDto(otherDTO, threeResultDTO, resultDto, detailResultDTO);
				if (null != resultDto) {
					list.add(resultDto);
					break;
				}
			}

		}

		if (null != list && list.size() > 0) {
			calculationKpiDAO.insertMedicalKpiData(list);
		}

	}

	/**
	 * ICD10准确率计算
	 * 
	 * @param dto
	 */
	public void selectAddDiagnose(CalculationKpiParmDTO dto) {
		KpiCalculationOtherDTO otherDTO = new KpiCalculationOtherDTO();
		otherDTO.setKpiCode("KPI0067");
		otherDTO.setKpiTime(dto.getKpiTime());

		try {
			SimpleDateFormat sft = new SimpleDateFormat("yyyy-MM");
			Date date = sft.parse(dto.getKpiTime());
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			otherDTO.setStrDate(cal.getTime());
			cal.add(Calendar.MONTH, 1);
			otherDTO.setEndDate(cal.getTime());
			calculationMedicalDiagnose(otherDTO);
		} catch (Exception e) {
			log.error(dto.getCalculationType() + "ICD10准确率计算错误：" + e.getCause().getCause().getMessage());
		}

	}

	private void calculationMedicalDiagnose(KpiCalculationOtherDTO otherDTO) {
		List<KpiCalculationResultDTO> resultList = new ArrayList<KpiCalculationResultDTO>();

		List<KpiCalculationResultDTO> DiagnoseNo = calculationKpiDAO.selectDiagnoseNoCount(otherDTO);
		List<KpiCalculationResultDTO> DiagnoseNoDesc = calculationKpiDAO.selectDiagnoseNoDescCount(otherDTO);
		otherDTO.setUseId("hcpmsdata");
		otherDTO.setVisitType("0");
		otherDTO.setIsValid("0");
		otherDTO.setPeriod("13");
		for (KpiCalculationResultDTO diagnoseNoDesc : DiagnoseNoDesc) {
			KpiCalculationResultDTO resultDto = null;
			for (KpiCalculationResultDTO Diagnose : DiagnoseNo) {
				resultDto = setKpiResultDto(otherDTO, diagnoseNoDesc, resultDto, Diagnose);
				if (null != resultDto) {
					resultList.add(resultDto);
					break;
				}
			}

		}

		if (null != resultList && resultList.size() > 0) {
			calculationKpiDAO.insertMedicalKpiData(resultList);
		}
	}

	/**
	 * 病案上传比例计算
	 * 
	 * @param dto
	 */
	public void selectAddCases(CalculationKpiParmDTO dto) {
		KpiCalculationOtherDTO otherDTO = new KpiCalculationOtherDTO();
		otherDTO.setKpiCode("KPI0066");
		otherDTO.setKpiTime(dto.getKpiTime());

		try {

			SimpleDateFormat sft = new SimpleDateFormat("yyyy-MM");
			Date date = sft.parse(dto.getKpiTime());
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			cal.add(Calendar.MONTH, -3);
			otherDTO.setStrDate(cal.getTime());
			cal.add(Calendar.MONTH, 1);
			otherDTO.setEndDate(cal.getTime());

			calculationMedicalCases(otherDTO);
		} catch (Exception e) {
			e.printStackTrace();
			log.error(dto.getCalculationType() + "病案上传比例计算错误：" + e.getCause().getCause().getMessage());
		}

	}

	/**
	 * 医院维度病案上传比例计算
	 * 
	 * @param dto
	 */
	public void calculationMedicalCases(KpiCalculationOtherDTO dto) {
		dto.setUseId("hcpmsdata");
		dto.setVisitType("1");
		dto.setIsValid("0");
		dto.setPeriod("13");
		List<KpiCalculationResultDTO> list = new ArrayList<KpiCalculationResultDTO>();
		List<KpiCalculationResultDTO> visitCount = calculationKpiDAO.selectMedicalVisitCount(dto);
		List<KpiCalculationResultDTO> medlPageCount = calculationKpiDAO.selectMedlPageCount(dto);
		for (KpiCalculationResultDTO medlPageDTO : medlPageCount) {
			KpiCalculationResultDTO resultDto = null;
			for (KpiCalculationResultDTO visitDTO : visitCount) {
				resultDto = setKpiResultDto(dto, medlPageDTO, resultDto, visitDTO);
				if (null != resultDto) {
					list.add(resultDto);
					break;
				}
			}

		}
		if (null != list && list.size() > 0) {
			calculationKpiDAO.insertMedicalKpiData(list);
		}
	}

	/**
	 * @param dto
	 * @param medlPageDTO
	 *            分子集合
	 * @param resultDto
	 * @param visitDTO
	 *            分母集合
	 * @return
	 */
	private KpiCalculationResultDTO setKpiResultDto(KpiCalculationOtherDTO dto, KpiCalculationResultDTO medlPageDTO,
			KpiCalculationResultDTO resultDto, KpiCalculationResultDTO visitDTO) {
		MathContext mc = new MathContext(4, RoundingMode.HALF_UP);
		if (visitDTO.getSociationCode().equals(medlPageDTO.getSociationCode())
				&& visitDTO.getMedicalCode().equals(medlPageDTO.getMedicalCode())) {
			resultDto = new KpiCalculationResultDTO();
			resultDto.setSociationCode(medlPageDTO.getSociationCode());
			resultDto.setMedicalCode(medlPageDTO.getMedicalCode());
			resultDto.setKpiCode(dto.getKpiCode());
			resultDto.setKpiTime(dto.getKpiTime());
			resultDto.setPeriod(dto.getPeriod());
			resultDto.setUseId(dto.getUseId());
			resultDto.setIsValid(dto.getIsValid());
			resultDto.setVisitType(dto.getVisitType());
			resultDto.setKpiParm1(medlPageDTO.getKpiValue());
			resultDto.setKpiParm2(visitDTO.getKpiValue());
			if (!"0".equals(visitDTO.getKpiValue().toString())) {
				resultDto.setKpiValue((medlPageDTO.getKpiValue().divide(visitDTO.getKpiValue(), 4,
						BigDecimal.ROUND_HALF_UP)).multiply(BigDecimal.TEN.pow(2), mc));
			}

		} else {
			return null;
		}
		return resultDto;
	}

}
